﻿namespace CodedUISample.StepDefinitions.PageObjects.CodedUIPage
{
    using System.Globalization;
    using System.Text;

    using CodedUISample.StepDefinitions.Context;

    using Microsoft.VisualStudio.TestTools.UITesting;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using UITest.CUIT.CuitControls.WinControls;

    /// <summary>
    ///     The coded ui calc.
    /// </summary>
    public class CodedUICalc : CodedUIBasePage
    {
        #region Fields

        /// <summary>
        ///     The add button.
        /// </summary>
        public CuitWinButton AddButton;

        /// <summary>
        ///     The calc window.
        /// </summary>
        public CuitWinWindow CalcWindow;

        /// <summary>
        ///     The equal button.
        /// </summary>
        public CuitWinButton EqualButton;

        /// <summary>
        ///     The result text box.
        /// </summary>
        public CuitWinText ResultTextBox;

        private readonly ApplicationUnderTest _aut;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="CodedUICalc"/> class.
        /// </summary>
        /// <param name="pageContext">
        /// The page context.
        /// </param>
        public CodedUICalc(SeleniumSamplePageContext pageContext)
        {
            this.PageContext = pageContext;
            this._aut = ApplicationUnderTest.Launch(@"C:\Windows\System32\calc.exe");
            this.CalcWindow = new CuitWinWindow("ClassName=CalcFrame");
            this.AddButton = new CuitWinButton(this.CalcWindow, "Name=Add");
            this.EqualButton = new CuitWinButton(this.CalcWindow, "Name=Equals");
            this.ResultTextBox = new CuitWinText(this.CalcWindow, "Name=Result");
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The assert result.
        /// </summary>
        /// <param name="result">
        /// The result.
        /// </param>
        public void AssertResult(int result)
        {
            // Orginal Microsoft Code is comment out, please use the AST Wrapper instead 
            /*
            var resultTextBox = new WinText(this._aut);
            resultTextBox.SearchProperties[UITestControl.PropertyNames.Name] = "Result";

            Assert.AreEqual(result.ToString(CultureInfo.InvariantCulture), resultTextBox.DisplayText);
             */
            Assert.AreEqual(result.ToString(CultureInfo.InvariantCulture), this.ResultTextBox.DisplayText);
        }

        /// <summary>
        ///     The click add.
        /// </summary>
        public void ClickAdd()
        {
            this.AddButton.Click();
        }

        /// <summary>
        ///     The click equal.
        /// </summary>
        public void ClickEqual()
        {
            this.EqualButton.Click();
        }

        /// <summary>
        /// The click number on the calculator.
        /// </summary>
        /// <param name="number">
        /// The number.
        /// </param>
        public void ClickNumberOnTheCalculator(int number)
        {
            char[] numbers = number.ToString(CultureInfo.InvariantCulture).ToCharArray();

            foreach (char c in numbers)
            {
                var numberButton = new CuitWinButton(this.CalcWindow, "Name=" + c);
                numberButton.Click();
            }
        }

        /// <summary>
        /// The entered into the calculator.
        /// </summary>
        /// <param name="number">
        /// The number.
        /// </param>
        public void EnteredIntoTheCalculator(int number)
        {
            Keyboard.SendKeys(this._aut, this.NumbersToSendKeysString(number));
        }

        /// <summary>
        ///     The press add.
        /// </summary>
        public void PressAdd()
        {
            Keyboard.SendKeys(this._aut, "{Add}");
        }

        /// <summary>
        ///     The press enter.
        /// </summary>
        public void PressEnter()
        {
            Keyboard.SendKeys(this._aut, "{Enter}");
        }

        #endregion

        #region Methods

        /// <summary>
        /// The numbers to send keys string.
        /// </summary>
        /// <param name="number">
        /// The number.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        protected string NumbersToSendKeysString(int number)
        {
            var result = new StringBuilder();
            char[] numbers = number.ToString(CultureInfo.InvariantCulture).ToCharArray();

            foreach (char c in numbers)
            {
                result.AppendFormat("{{NumPad{0}}}", c);
            }

            return result.ToString();
        }

        #endregion
    }
}